﻿using Microsoft.TeamFoundation.TestManagement.Client;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HybridLab.Workflow.Activities.UI
{
	public partial class TestSuiteDialog : Form
	{
		private List<ITestSuiteBase> selectedSuites;
		private List<ITestSuiteBase> testSuiteList;

		private TestSuiteDialog()
		{
			InitializeComponent();
			testSuiteTreeView.AfterCheck += new TreeViewEventHandler(this.testSuiteTreeView_AfterCheck);
			errorControl = new ErrorControl(this.testSuiteTreeView.Size);
			errorControl.Margin = new Padding(12, 3, 12, 3);
			okButton.Enabled = false;
		}

		internal TestSuiteDialog(List<ITestSuiteBase> testSuiteList, List<ITestSuiteBase> selectedSuites)
			: this()
		{
			if (testSuiteList != null)
			{
				this.testSuiteList = testSuiteList;
				this.selectedSuites = selectedSuites;
				base.Load += new EventHandler(DialogSelectTestSuite_Load);
			}
		}

		private void DialogSelectTestSuite_Load(object senderArgs, EventArgs eventArgs)
		{
			Cursor = Cursors.WaitCursor;
			errorControl.SetInformationMessage("Initializing...");
			testSuiteTreeView.Nodes.Clear();
			BackgroundWorker worker = new BackgroundWorker();
			worker.DoWork += delegate(object sender, DoWorkEventArgs e)
			{
				e.Result = PopulateTree();
			};
			worker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e)
			{
				testSuiteTreeView.Focus();
				errorControl.SetInformationMessage(null);
				Cursor = Cursors.Default;
				if (e.Error != null)
				{
					errorControl.SetErrorMessage("An error occurred while initializing the test suites");
					OnError();
				}
				else
				{
					testSuiteTreeView.Nodes.Add(e.Result as TreeNode);
					okButton.Enabled = true;
				}
			};
			worker.RunWorkerAsync();
		}

		private void FindCheckedNodes(TreeNodeCollection treeNodeCollection, List<ITestSuiteBase> suites)
		{
			if (treeNodeCollection != null)
			{
				foreach (TreeNode node in treeNodeCollection)
				{
					if (node.Checked)
					{
						suites.Add(node.Tag as ITestSuiteBase);
					}
					if ((node.Nodes != null) && (node.Nodes.Count > 0))
					{
						FindCheckedNodes(node.Nodes, suites);
					}
				}
			}
		}

		private void LoadChildNodes(TreeNode parentNode)
		{
			if (parentNode != null)
			{
				ITestSuiteBase tag = parentNode.Tag as ITestSuiteBase;
				if (tag.TestSuiteType == TestSuiteType.StaticTestSuite)
				{
					IStaticTestSuite suite = tag as IStaticTestSuite;
					if ((suite != null) && ((suite.SubSuites != null) && (suite.SubSuites.Count != 0)))
					{
						using (IEnumerator<ITestSuiteBase> enumerator = suite.SubSuites.OrderBy<ITestSuiteBase, string>(delegate(ITestSuiteBase c)
						{
							return c.Title;
						}).GetEnumerator())
						{
							Func<ITestSuiteBase, bool> predicate = null;
							ITestSuiteBase child;
							while (enumerator.MoveNext())
							{
								child = enumerator.Current;
								TreeNode node = new TreeNode(child.Title);
								node.Tag = child;
								parentNode.Nodes.Add(node);
								if (selectedSuites != null)
								{
									if (predicate == null)
									{
										predicate = delegate(ITestSuiteBase s)
										{
											return s.Id == child.Id;
										};
									}
									if (selectedSuites.Any<ITestSuiteBase>(predicate))
									{
										node.Checked = true;
									}
								}
								LoadChildNodes(node);
							}
						}
					}
				}
			}
		}

		private void OnError()
		{
			base.Close();
		}

		private TreeNode PopulateTree()
		{
			TreeNode parentNode = null;
			ITestSuiteBase rootSuite = testSuiteList.FirstOrDefault(s => s.IsRoot);
			if (rootSuite != null)
			{
				parentNode = new TreeNode(rootSuite.Title);
				parentNode.Tag = rootSuite;
				if (selectedSuites != null)
				{
					parentNode.Checked = selectedSuites.Any(s => s.Id == rootSuite.Id);
				}
				LoadChildNodes(parentNode);
				parentNode.ExpandAll();
			}
			return parentNode;
		}

		private void testSuiteTreeView_AfterCheck(object sender, TreeViewEventArgs e)
		{
			List<ITestSuiteBase> suites = new List<ITestSuiteBase>();
			FindCheckedNodes(testSuiteTreeView.Nodes, suites);
			if (suites.Count == 0)
			{
				errorControl.SetErrorMessage("At least one test suite must be selected");
				okButton.Enabled = false;
			}
			else
			{
				errorControl.SetErrorMessage(null);
				okButton.Enabled = true;
			}
		}

		public List<ITestSuiteBase> SelectedSuites
		{
			get
			{
				List<ITestSuiteBase> suites = new List<ITestSuiteBase>();
				try
				{
					FindCheckedNodes(testSuiteTreeView.Nodes, suites);
				}
				catch
				{
				}
				return suites;
			}
		}
	}
}
